package com.gitee.chili.leisure.message;

import com.gitee.chili.leisure.ResponseCode;
import com.gitee.chili.leisure.RoomManager;
import com.gitee.chili.leisure.SimpleBeanFactory;
import com.gitee.chili.leisure.core.AbstractDefaultMessage;
import com.gitee.chili.leisure.core.Packet;
import com.gitee.chili.leisure.exception.NotFoundMemberException;
import com.gitee.chili.leisure.game.Player;
import com.gitee.chili.leisure.game.RoomDetail;
import com.gitee.chili.leisure.model.HallModel;
import com.gitee.chili.leisure.model.MessageCmdEnum;
import com.gitee.chili.leisure.service.SpecificTaskTransferClient;
import com.gitee.chili.leisure.util.AuxiliaryChannel;
import com.gitee.chili.leisure.util.AuxiliaryRoom;
import com.google.protobuf.InvalidProtocolBufferException;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.Optional;

/**
 * 离开房间消息
 *
 * @author week solider
 * @since 2020.09.10
 */
@Slf4j
public class LeaveRoom extends AbstractDefaultMessage {

    public LeaveRoom(Packet packet, Channel channel) {
        super(packet, channel);
    }

    @Override
    protected void decoder(byte[] body) throws InvalidProtocolBufferException {

        HallModel.LeaveRoomCmd leaveRoom = HallModel.LeaveRoomCmd.parseFrom(body);

        if (Objects.isNull(leaveRoom)) {
            log.error("退出房间异常");
            return;
        }

        Long memberId = getMemberId();
        SpecificTaskTransferClient transferClient = SimpleBeanFactory.getBean(SpecificTaskTransferClient.class);
        asserts(transferClient.leaveRoom(getRoomNum(), memberId));
    }

    @Override
    public Packet parseBody() {

        Long memberId = getMemberId();
        Long roomNum = getRoomNum();

        RoomDetail roomDetail = RoomManager.obtain(roomNum);

        // 这里需要强制解散
        if (memberId.equals(roomDetail.getHomeowner())) {
            // 房间解散
            return AuxiliaryRoom.dissolved(roomNum);
        }

        // 获取玩家信息
        Optional<? extends Player> optional = roomDetail.getPlayers()
                .stream().filter(p -> p.getUserId().equals(memberId)).findFirst();
        if (!optional.isPresent()) {
            AuxiliaryChannel.errorMessage(getChannel(), getPacket().getCmd(), ResponseCode.CACHE_MISS);
            log.error("查找玩家: {} , 信息丢失", memberId);
            throw new NotFoundMemberException("玩家信息丢失");
        }
        Player player = optional.get();

        // 填充数据包
        HallModel.NotifyMemberLeaveRoomResult.Builder builder = HallModel.NotifyMemberLeaveRoomResult.newBuilder();
        builder.setSeatNum(player.getPosition());
        builder.setLeaveRoomType(HallModel.NotifyMemberLeaveRoomResult.LeaveRoomType.FORCED_EXIT);

        // 退出房间
        AuxiliaryRoom.exit(roomNum, memberId);

        return Packet.newPacket(MessageCmdEnum.Command.NOTIFY_MEMBER_LEAVE_ROOM, builder.build().toByteArray());
    }
}
